		TITLE	FARINST - Copyright (C) 1994 SLR Systems

		INCLUDE	MACROS
		INCLUDE	SYMBOLS
		INCLUDE	CDDATA
		INCLUDE	EXES

		PUBLIC	FAR_INSTALL,COMDAT_INSTALL,TRY_UNDECORATED


		.DATA

		EXTERNDEF	SYMBOL_TEXT:BYTE,EXETYPE_FLAG:BYTE,FLOAT_FLAG:BYTE,FLOAT_TYPE:BYTE,COMDAT_FLAGS:BYTE

		EXTERNDEF	SYM_HASH_MOD:DWORD,SYM_HASH:DWORD,SYMBOL_LENGTH:DWORD,SYMBOL_HASH:DWORD,SYM_HASH_PHYS:DWORD
		EXTERNDEF	LOCAL_HASH_TABLE_PTR:DWORD,LOCAL_HASH_TABLE_PTR_OLD:DWORD,LOCAL_HASH:DWORD,UNDECO_HASH_PHYS:DWORD
		EXTERNDEF	UNDECO_HASH:DWORD,FIRST_UNDECORATED_GINDEX:DWORD

		EXTERNDEF	SYMBOL_GARRAY:STD_PTR_S,LNAME_LARRAY:LARRAY_STRUCT

		EXTERNDEF	CASE_STRING_COMPARE:DWORD,OPTI_HASH:DWORD


		.CODE	PASS1_TEXT

		externdef	_comdat_install:proc
		externdef	_do_near_install:proc
		EXTERNDEF	ENTRYNAME_POOL_GET:PROC

COMDAT_INSTALL	PROC
		push	EAX
		mov	ECX,ESP
		push	ECX
		push	EAX
		call	_comdat_install
		add	ESP,8
		pop	ECX
		ret
COMDAT_INSTALL	ENDP

		public _far_install
_far_install	proc
		mov	EDX,4[ESP]
		call	FAR_INSTALL
		mov	EDX,8[ESP]
		mov	[EDX],ECX
		ret
_far_install	endp

FAR_INSTALL	PROC
		;
		;EDX IS HASH VALUE, CONVERT IT
		;
		;RETURN EAX IS LOGICAL, ECX IS PHYS
		;
		PUSH	EBX
		MOV	EAX,EDX

		MOV	ECX,SYM_HASH_MOD
		MOV	EBX,DPTR SYMBOL_TEXT

		TEST	ECX,ECX
		JNZ	NEAR_INSTALL

		CMP	BX,'  '
		JZ	NEAR_INSTALL

		XOR	EDX,EDX
		MOV	EBX,SYM_HASH_PHYS

		HASHDIV	SYM_HASH		;EDX IS HASH VALUE

		PUSHM	EDI,ESI
FAR_CONT:
		MOV	EAX,[EBX+EDX*4]
		LEA	EBX,[EBX+EDX*4 - SYMBOL_STRUCT._S_NEXT_HASH_GINDEX]
FAR_NEXT:
		TEST	EAX,EAX
		JZ	DO_FAR_INSTALL

		CONVERT	EBX,EAX,SYMBOL_GARRAY
		ASSUME	EBX:PTR SYMBOL_STRUCT
		;
		;PROBABLE MATCH, NEED COMPARE...
		;
		MOV	EDX,EAX

		MOV	ECX,SYMBOL_LENGTH
		MOV	EDI,OFF SYMBOL_TEXT

		LEA	ESI,[EBX]._S_NAME_TEXT
		;
		;IF CASE IS SIGNIFICANT, OR ALL UPPER, OR ALL LOWER
		;USE THIS ROUTINE.  IF IGNORE CASE BUT PRESERVE...
		;
		CALL	CASE_STRING_COMPARE

		MOV	EAX,[EBX]._S_NEXT_HASH_GINDEX
FAR_NEXT_1:
		JNZ	FAR_NEXT
FAR_MATCH:
		POPM	ESI,EDI

		MOV	ECX,EBX
		POP	EBX

		MOV	EAX,EDX
		CMP	ESP,-1			;EAX IS GINDEX, ECX IS PHYS

		RET

FAR_INSTALL	ENDP


DO_FAR_INSTALL	PROC	PRIVATE
		;
		;DS:BX GETS POINTER...
		;
		MOV	EAX,SYMBOL_LENGTH
if	fg_segm
		MOV	ECX,DPTR SYMBOL_TEXT+4

		CMP	EAX,6			;ANY CHANCE OF FLOAT_SYMS?
		JNZ	L2$

		CMP	CX,'QQ'
		JZ	MFE
L2$:
endif
		ADD	EAX,SIZE SYMBOL_STRUCT-3
		SSYM_POOL_ALLOC			;ES:DI IS PHYS, AX LOG

		MOV	EDI,EAX
		INSTALL_POINTER_GINDEX	SYMBOL_GARRAY
		MOV	[EBX]._S_NEXT_HASH_GINDEX,EAX

		MOV	ESI,OFF SYMBOL_TEXT
		PUSH	EAX

		XOR	EAX,EAX
		MOV	ECX,SYMBOL_STRUCT._S_NAME_TEXT/4

		MOV	EDX,[ESI-4]
		MOV	EBX,EDI

		SHR	EDX,2

		OPTI_STOSD

		LEA	ECX,[EDX+1]
		POP	EAX

		REP	MOVSD

		POP	ESI
		;
		;IS IT A FLOATING-PT EMULATED SYMBOL?
		;
		MOV	DL,FLOAT_FLAG

		TEST	DL,DL
		JNZ	L5$

		MOV	EDX,DPTR SYMBOL_TEXT
		MOV	ECX,DPTR SYMBOL_TEXT+4

		CMP	EDX,'mi__'
		JNZ	MFS_RET

		CMP	CX,'_p'
		JNZ	MFS_RET

		MOV	[EBX]._S_NSYM_TYPE,NSYM__IMP__UNREF

MFS_RET:
		POPM	EDI
		MOV	ECX,EBX

		POP	EBX
		MOV	EDX,FIRST_UNDECORATED_GINDEX

		TEST	EDX,EDX
		JNZ	TRY_UNDECORATED

		RET				;DS:BX IS PHYS, AX IS GINDEX


if	fg_segm


MFE:
		MOV	CL,SYMBOL_TEXT

		CMP	CL,'F'
		JNZ	L2$

		CMP	SYMBOL_TEXT+3,'R'

		JNZ	L2$

		JMP	MFE_0

L5$:
		XCHG	CX,WPTR FLOAT_FLAG

		MOV	[EBX]._S_REF_FLAGS,CL

		MOV	BPTR [EBX]._S_FLOAT_TYPE,CH
		JMP	MFS_RET
endif


if	fg_segm
MFE_0:
		MOV	AX,WPTR SYMBOL_TEXT+1
		MOV	EDI,OFF FLT_EMU_TXT
		MOV	ECX,9
		REPNE	SCASW
		MOV	EAX,6
		JNZ	L21$
		BITT	NOEMUFLOAT_FLAG		;DELETE FLOATING FIXUPS?
		JNZ	MFE_1			;YES, JUMP
		BITT	PROTMODE		;TYPE IS 0 FOR OS2 && PROTMODE
		JZ	L3$
		CMP	EXETYPE_FLAG,OS2_SEGM_TYPE	;OS/2 ?
		JZ	MFE_1			;YES, JUMP
L3$:
		SUB	ECX,2			;LAST FEW DON'T...
		JC	MFE_1
MFE_3:
		MOV	EAX,8
		MOV	FLOAT_TYPE,CL
		MOV	FLOAT_FLAG,MASK S_FLOAT_SYM
L21$:
		JMP	L2$

MFE_1:
		XOR	CL,CL
		JMP	MFE_3

endif

DO_FAR_INSTALL	ENDP


UNDECO_STRUCT	STRUC

UN_SYMBOL_LENGTH_BP	DD	?
UN_SYMBOL_TEXT_BP	DB	SYMBOL_TEXT_SIZE DUP(?)

UNDECO_STRUCT	ENDS


FIX	MACRO	X

X	EQU	([EBP-SIZE UNDECO_STRUCT].(X&_BP))

	ENDM


FIX	UN_SYMBOL_LENGTH
FIX	UN_SYMBOL_TEXT

		ASSUME	EBX:NOTHING

TRY_UNDECORATED	PROC

		PUSHM	EBP,EDI

                MOV	EDI,SYMBOL_TEXT_SIZE/2 - 4
		MOV	EBP,ESP
                SUB	ESP,EDI
                PUSH	EBP
                SUB	ESP,EDI
                PUSH	EBP
                PUSH	EBP
		ASSUME	EBP:PTR UNDECO_STRUCT

		PUSHM	ESI,ECX,EBX,EAX

		GETT	AL,AFTER_DEF_DONE

		OR	AL,AL
		JZ	NO_MATCH

		MOV	ESI,OFF SYMBOL_TEXT
		LEA	EDI,UN_SYMBOL_TEXT

		GETT	AL,OUTPUT_PE
		MOV	ECX,SYMBOL_LENGTH

		TEST	AL,AL
		JNZ	YES_FUZZY
		;
		;FOR 16-BIT OUTPUT, SEARCH USING COMPLETE SYMBOL
		;
		TEST	ECX,ECX
		JZ	NO_MATCH

		MOV	EAX,ECX
		MOV	UN_SYMBOL_LENGTH,ECX

		SHR	ECX,2

		INC	ECX

		REP	MOVSD

		LEA	ESI,UN_SYMBOL_TEXT
		JMP	L4$

NO_MATCH:
		POPM	EAX,EBX,ECX,ESI

		MOV	ESP,EBP
		XOR	EDX,EDX			;CLEAR CARRY

		POPM	EDI,EBP

		RET

YES_FUZZY:
		MOV	AL,[ESI]
		INC	ESI

		CMP	AL,'_'
		JZ	L1$

		CMP	AL,'@'
		JZ	L1$

		CMP	AL,'?'
		JNZ	L2$
L1$:
		MOV	AL,[ESI]
		INC	ESI
L2$:
		MOV	[EDI],AL
		INC	EDI

		CMP	AL,'@'
		JZ	L3$

		CMP	AL,0
		JNZ	L1$
L3$:
		XOR	EAX,EAX
		LEA	ESI,UN_SYMBOL_TEXT

		MOV	DPTR [EDI-1],EAX
		MOV	EAX,EDI

		SUB	EAX,ESI

		CMP	EAX,2
		JB	NO_MATCH

		DEC	EAX

		MOV	UN_SYMBOL_LENGTH,EAX
L4$:
		CALL	OPTI_HASH

		MOV	EAX,EDX
		XOR	EDX,EDX

		MOV	EBX,UNDECO_HASH_PHYS

		HASHDIV	UNDECO_HASH		;EDX IS HASH VALUE

FAR_CONT:
		MOV	EAX,[EBX+EDX*4]
		LEA	EBX,[EBX+EDX*4 - SYMBOL_STRUCT._S_NEXT_HASH_GINDEX]
FAR_NEXT:
		TEST	EAX,EAX
		JZ	NO_MATCH

		CONVERT	EBX,EAX,SYMBOL_GARRAY
		ASSUME	EBX:PTR SYMBOL_STRUCT
		;
		;PROBABLE MATCH, NEED COMPARE...
		;
		MOV	EDX,EAX

		MOV	ECX,UN_SYMBOL_LENGTH
		LEA	EDI,UN_SYMBOL_TEXT

		LEA	ESI,[EBX]._S_NAME_TEXT
		;
		;IF CASE IS SIGNIFICANT, OR ALL UPPER, OR ALL LOWER
		;USE THIS ROUTINE.  IF IGNORE CASE BUT PRESERVE...
		;
		CALL	CASE_STRING_COMPARE

		MOV	EAX,[EBX]._S_NEXT_HASH_GINDEX
FAR_NEXT_1:
		JNZ	FAR_NEXT
		;
		;FOUND A FUZZY MATCH...
		;
		GETT	AL,FUZZY_JUST_CHECK
		MOV	EDX,EBX

		OR	AL,AL
		JNZ	END_JUST_CHECK

		MOV	EAX,SYMBOL_LENGTH
		MOV	ECX,UN_SYMBOL_LENGTH

		CMP	EAX,ECX
		JNZ	FUZZY_MATCH
		;
		;EXACT MATCH!
		;
		POP	EAX			;REAL INTERNAL GINDEX
		MOV	[EBX]._S_REF_FLAGS,MASK UNDECO_EXACT

		MOV	[EBX]._S_N_NCPP_MATCHES,1

		MOV	[EBX]._S_LAST_NCPP_MATCH,EAX
		MOV	EDX,EBX
END_MATCH:
		POPM	EBX,ECX,ESI
		MOV	ESP,EBP

		POPM	EDI,EBP

		RET

END_JUST_CHECK:
		POP	EAX
		JMP	END_MATCH

FUZZY_MATCH:
		;
		;TRICKIER...
		;
		MOV	CL,[EBX]._S_REF_FLAGS
		MOV	AL,SYMBOL_TEXT

		AND	CL,MASK UNDECO_EXACT
		JNZ	NO_MATCH

		CMP	AL,'?'
		JZ	FUZZY_CPP_MATCH

		MOV	ECX,[EBX]._S_N_NCPP_MATCHES

		TEST	ECX,ECX
		JNZ	MULTI_NCPP

		POP	EAX
		INC	ECX

		MOV	[EBX]._S_LAST_NCPP_MATCH,EAX
		MOV	[EBX]._S_N_NCPP_MATCHES,ECX

		MOV	EDX,EBX
		JMP	END_MATCH

MULTI_NCPP:
		CMP	ECX,1
		JNZ	MULTI_NCPP_CONT

		XOR	EDX,EDX
		MOV	EAX,[EBX]._S_LAST_NCPP_MATCH

		MOV	[EBX]._S_LAST_NCPP_MATCH,EDX
		CALL	DO_ANOTHER_NCPP
MULTI_NCPP_CONT:
		POP	EAX
		CALL	DO_ANOTHER_NCPP

		MOV	EDX,EBX
		JMP	END_MATCH

DO_ANOTHER_NCPP:
		PUSHM	ECX,EAX

		MOV	EAX,8
		CALL	ENTRYNAME_POOL_GET

		POP	EDX
		MOV	ECX,[EBX]._S_LAST_NCPP_MATCH

		MOV	[EAX],EDX
		MOV	[EAX+4],ECX

		POP	ECX
		MOV	[EBX]._S_LAST_NCPP_MATCH,EAX

		INC	ECX
		MOV	EAX,EDX

		MOV	[EBX]._S_N_NCPP_MATCHES,ECX

		RET

FUZZY_CPP_MATCH:
		MOV	ECX,[EBX]._S_N_CPP_MATCHES

		TEST	ECX,ECX
		JNZ	MULTI_CPP

		POP	EAX
		INC	ECX

		MOV	[EBX]._S_LAST_CPP_MATCH,EAX
		MOV	[EBX]._S_N_CPP_MATCHES,ECX

		MOV	EDX,EBX
		JMP	END_MATCH

MULTI_CPP:
		CMP	ECX,1
		JNZ	MULTI_CPP_CONT

		XOR	EDX,EDX
		MOV	EAX,[EBX]._S_LAST_CPP_MATCH

		MOV	[EBX]._S_LAST_CPP_MATCH,EDX
		CALL	DO_ANOTHER_CPP
MULTI_CPP_CONT:
		POP	EAX
		CALL	DO_ANOTHER_CPP

		MOV	EDX,EBX
		JMP	END_MATCH

DO_ANOTHER_CPP:
		PUSHM	ECX,EAX

		MOV	EAX,8
		CALL	ENTRYNAME_POOL_GET

		POP	EDX
		MOV	ECX,[EBX]._S_LAST_CPP_MATCH

		MOV	[EAX],EDX
		MOV	[EAX+4],ECX

		POP	ECX
		MOV	[EBX]._S_LAST_CPP_MATCH,EAX

		INC	ECX
		MOV	EAX,EDX

		MOV	[EBX]._S_N_CPP_MATCHES,ECX

		RET


TRY_UNDECORATED	ENDP


NEAR_INIT:
		;
		;FIRST USE OF LOCAL SYMBOL...
		;
		XOR	EAX,EAX
		MOV	EDI,LOCAL_HASH_TABLE_PTR_OLD	;SAME BLOCK...

		MOV	ECX,LOCAL_HASH
		MOV	EBX,EDI

		OPTI_STOSD

		MOV	LOCAL_HASH_TABLE_PTR,EBX
		JMP	NEAR_CONT

NEAR_INSTALL	PROC
		;
		;A LOCAL SYMBOL, USE DIFFERENT HASH TABLE
		;
		XOR	EDX,EDX
		PUSH	EDI

		HASHDIV	LOCAL_HASH

		MOV	EBX,LOCAL_HASH_TABLE_PTR
		PUSH	ESI

		TEST	EBX,EBX
		JZ	NEAR_INIT
NEAR_CONT::
		MOV	EAX,DPTR [EBX+EDX*4]
		LEA	EBX,[EBX+EDX*4 - SYMBOL_STRUCT._S_NEXT_HASH_GINDEX]
NEAR_NEXT:
		OR	EAX,EAX
		JZ	DO_NEAR_INSTALL

		MOV	EDX,EAX
		CONVERT	EBX,EAX,SYMBOL_GARRAY
		;
		;PROBABLE MATCH, NEED COMPARE...
		;
		MOV	ECX,SYMBOL_LENGTH
		MOV	EDI,OFF SYMBOL_TEXT

		LEA	ESI,[EBX]._S_NAME_TEXT
		;
		;IF CASE IS SIGNIFICANT, OR ALL UPPER, OR ALL LOWER
		;USE THIS ROUTINE.  IF IGNORE CASE BUT PRESERVE...
		;
		CALL	CASE_STRING_COMPARE

		MOV	EAX,[EBX]._S_NEXT_HASH_GINDEX
NEAR_NEXT_1:
		JNZ	NEAR_NEXT
NEAR_MATCH:
		MOV	EAX,EDX
		MOV	ECX,EBX

		CMP	ESP,-1			;AX IS GINDEX, DS:BX IS PHYS
		POPM	ESI,EDI,EBX

		RET

NEAR_INSTALL	ENDP


DO_NEAR_INSTALL	PROC
		push	ECX
		mov	ECX,ESP
		push	ECX
		push	EBX
		call	_do_near_install
		add	ESP,8
		pop	ECX
		or	DL,DL
		POPM	ESI,EDI,EBX
		ret

		;
		;DS:BX GETS POINTER...
		;
		MOV	EAX,SYMBOL_LENGTH
;		MOV	DX,DI
		MOV	ESI,EBX

		ADD	EAX,SIZE SYMBOL_STRUCT-3
		TILLMIDDLE_POOL_ALLOC

		MOV	EDI,EAX
		INSTALL_POINTER_GINDEX	SYMBOL_GARRAY
		MOV	[ESI].SYMBOL_STRUCT._S_NEXT_HASH_GINDEX,EAX

		MOV	ESI,OFF SYMBOL_TEXT
		PUSH	EAX

		XOR	EAX,EAX
		MOV	ECX,SYMBOL_STRUCT._S_NAME_TEXT/4

		MOV	EDX,[ESI-4]
		MOV	EBX,EDI

		SHR	EDX,2

		OPTI_STOSD

		LEA	ECX,[EDX+1]
		MOV	AL,MASK S_SPACES

		REP	MOVSD

		MOV	[EBX]._S_REF_FLAGS,AL
		OR	CL,CL

		POP	EAX
		MOV	ECX,EBX

		POPM	ESI,EDI,EBX

		RET				;ECX IS PHYS, EAX IS GINDEX

DO_NEAR_INSTALL	ENDP


		.DATA

		EVEN
if	fg_segm

FLT_EMU_TXT	DB	'IW','ID','IE','IC','IS','IA','JA','JC','JS'

endif


		END

